package org.jeecg.modules.rooms.service;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang3.ObjectUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.modules.rooms.entity.CesGoodStockRecords;
import org.jeecg.modules.rooms.DTO.CesGoodStockRecordsDto;
import org.jeecg.modules.rooms.entity.CesGoods;
import org.jeecg.modules.rooms.mapper.CesGoodStockRecordsMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.integration.redis.util.RedisLockRegistry;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.transaction.Transactional;
import java.time.LocalDateTime;
import java.util.concurrent.locks.Lock;

/**
 * <p>
 * 商品进退货记录表 服务实现类
 * </p>
 *
 * @author fendo
 * @since 2023-03-14
 */
@Service
public class CesGoodStockRecordsServiceImpl extends ServiceImpl<CesGoodStockRecordsMapper, CesGoodStockRecords> implements IService<CesGoodStockRecords> {
    private static  final Logger logger = LoggerFactory.getLogger(CesGoodStockRecordsServiceImpl.class);
    @Resource
    private CesGoodStockRecordsMapper stockRecordsMapper;

    @Resource
    private CesGoodsServiceImpl goodsService;

    @Resource
    private RedisLockRegistry redisLockRegistry;

    @Transactional(rollbackOn = Exception.class)
    public Result create(CesGoodStockRecordsDto dto){
        /**
         * 这里需要锁资源  分布式事务锁 采用redis 实现  考虑到数据操作的原子性 (设置redis 锁 统一要同步设置过期时间 60 秒 )
         */
        String key = String.format("stock::record::create:%s:%s", dto.getGoodId(),dto.getHotelId());
        Lock lock = redisLockRegistry.obtain(key);  //获取锁资源

        logger.info("lock begin");
        logger.info("创建 redis 资源锁 key:{}", key);
        try{
            //开启锁
            lock.lock();
            logger.info("开启 redis 资源锁");

            //查询商品是否存在
            CesGoods goods = goodsService.fetchByIdAndHotelId(dto.getGoodId(),dto.getHotelId());
            if(ObjectUtils.isEmpty(goods)) return Result.error("商品数据未找到!");

            //业务逻辑处理 减库存 加库存 这样写更清晰
            int num = dto.getGoodNum().intValue();
            int count = goods.getInventory().intValue();

            switch (dto.getType().intValue()){
                case 1: //进货
                    goods.setInventory(count + num);
                    break;
                case 2:
                    //如果商品的库存数量 小于 需要减去库存的数量 则 提示错误
                    if(count < num) throw new JeecgBootException("该商品的库存数量小于需要减去的数量,请重新填入!");
                    goods.setInventory(count - num);
                    break;
            }

            //先保存 记录数据 再去扣除库存
            CesGoodStockRecords records = new CesGoodStockRecords();
            BeanUtil.copyProperties(dto,records);
            records.setCreateAt(LocalDateTime.now());
            records.setUpdateAt(LocalDateTime.now());
            records.setInvalid(false);

            int insert_count = stockRecordsMapper.insert(records);
            //修改商品数据
            if(num > 0){ //必须是大于0 再去修改
                goods.setUpdateAt(LocalDateTime.now());
                boolean flag = goodsService.updateById(goods);
                if(!flag) throw new JeecgBootException("修改商品失败!");
            }
        }catch (Exception e){
            return Result.error(e.getMessage());
        }finally {
            //释放锁
            lock.unlock();
            logger.info("释放 redis 资源锁");
            logger.info("lock end");
        }
        return Result.ok("创建成功!");
    }




}
